#ifndef OMG_DDS_BUILTINTOPICS_HPP_ 
#define OMG_DDS_BUILTINTOPICS_HPP_

/* Copyright (c) 2009-2010, Real-Time Innovations, Inc.
 * Copyright (c) 2010, Object Management Group, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 
 * - Redistributions of source code must retain the above copyright notice,
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * - Neither the names of the above copyright holders nor the names of their
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL A COPYRIGHT HOLDER OR CONTRIBUTOR BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */


namespace dds {
    namespace domain {
        namespace discovery {
            template <typename T>
            class builtin_topic_traits
            {
                // empty
            };
        }
    }
}


#define OMG_DDS_BUILTIN_TOPIC_TRAITS(TYPE, TYPE_NAME, TOPIC_NAME) \
    namespace dds {                                 \
        namespace domain {                          \
            namespace discovery {                   \
                template <>                         \
                class builtin_topic_traits<TYPE>    \
                {                                   \
                public:                             \
                    typedef TYPE DataType;          \
                    static const char* type_name()  { return TYPE_NAME; }   \
                    static const char* topic_name() { return TOPIC_NAME; }  \
                };                                  \
            }                                       \
        }                                           \
    }


template <typename DELEGATE>
class tdds::domain::discovery::BuiltinTopicKey : public dds::core::Value
{
    OMG_DDS_VALUE_TYPE(BuiltinTopicKey)

public:
    static const int VALUE_LENGTH;  // = 16, per DDS-RTPS

    const uint8_t* get_value() const;

    // --- State: --- //
private:
    friend class OMG_DDS_BUILTIN_TOPIC_KEY_DELEGATE;
    DELEGATE impl_;
};


template <typename DELEGATE>
class tdds::domain::discovery::ParticipantBuiltinTopicData :
    public dds::core::Value
{
    OMG_DDS_VALUE_TYPE(ParticipantBuiltinTopicData)

public:
    const dds::domain::discovery::BuiltinTopicKey& key() const;

    const dds::core::policy::UserData& user_data() const;

    // --- State: --- //
private:
    friend class OMG_DDS_PARTICIPANT_BUILTIN_TOPIC_DATA_DELEGATE;
    DELEGATE impl_;
};

OMG_DDS_BUILTIN_TOPIC_TRAITS(ParticipantBuiltinTopicData, "DDS_ParticipantBuiltinTopicData", "DCPSParticipant")


template <typename DELEGATE>
class tdds::domain::discovery::TopicBuiltinTopicData : public dds::core::Value
{
    OMG_DDS_VALUE_TYPE(TopicBuiltinTopicData)

public:
    const dds::domain::discovery::BuiltinTopicKey& key() const;
    
    const std::string& name() const;
    
    const std::string& type_name() const;

#ifdef OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT
    const dds::core::StringSeq& equivalent_type_name();

    const dds::core::StringSeq& base_type_name() const;

    const dds::type::typeobject::TypeObject& type() const;
#endif  // defined(OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT)

    const dds::core::policy::Durability& durability() const;
    
#ifdef OMG_DDS_PERSISTENCE_SUPPORT
    const dds::core::policy::DurabilityService& durability_service() const;
#endif  // OMG_DDS_PERSISTENCE_SUPPORT

    const dds::core::policy::Deadline& deadline() const;

    const dds::core::policy::LatencyBudget& latency_budget() const;

    const dds::core::policy::Liveliness& liveliness() const;

    const dds::core::policy::Reliability& reliability() const;

    const dds::core::policy::TransportPriority& transport_priority() const;

    const dds::core::policy::Lifespan& lifespan() const;

    const dds::core::policy::DestinationOrder& destination_order() const;

    const dds::core::policy::History& history() const;

    const dds::core::policy::ResourceLimits& resource_limits() const;

    const dds::core::policy::Ownership& ownership() const;

    const dds::core::policy::TopicData& topic_data() const;

#ifdef OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT
    const dds::core::policy::DataRepresentation& representation() const;

    const dds::core::policy::TypeConsistencyEnforcement&
    type_consistency() const;
#endif  // defined(OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT)

    // --- State: --- //
private:
    friend class OMG_DDS_TOPIC_BUILTIN_TOPIC_DATA_DELEGATE;
    DELEGATE impl_;
};

OMG_DDS_BUILTIN_TOPIC_TRAITS(TopicBuiltinTopicData, "DDS_TopicBuiltinTopicData", "DCPSTopic")


template <typename DELEGATE>
class tdds::domain::discovery::PublicationBuiltinTopicData :
    public dds::core::Value
{
    OMG_DDS_VALUE_TYPE(PublicationBuiltinTopicData)

public:
    const dds::domain::discovery::BuiltinTopicKey& key() const;

    const dds::domain::discovery::BuiltinTopicKey& participant_key() const;

    const std::string& topic_name() const;

    const std::string& type_name() const;

#ifdef OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT
    const dds::core::StringSeq& equivalent_type_name();

    const dds::core::StringSeq& base_type_name() const;

    const dds::type::typeobject::TypeObject& type() const;
#endif  // defined(OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT)

    const dds::core::policy::Durability& durability() const;

#ifdef OMG_DDS_PERSISTENCE_SUPPORT
    const dds::core::policy::DurabilityService& durability_service() const;
#endif  // OMG_DDS_PERSISTENCE_SUPPORT

    const dds::core::policy::Deadline& deadline() const;

    const dds::core::policy::LatencyBudget& latency_budget() const;

    const dds::core::policy::Liveliness& liveliness() const;

    const dds::core::policy::Reliability& reliability() const;

    const dds::core::policy::Lifespan& lifespan() const;

    const dds::core::policy::UserData& user_data() const;

    const dds::core::policy::Ownership& ownership() const;

#ifdef OMG_DDS_OWNERSHIP_SUPPORT
    const dds::core::policy::OwnershipStrength& ownership_strength() const;
#endif  // OMG_DDS_OWNERSHIP_SUPPORT

    const dds::core::policy::DestinationOrder& destination_order() const;

    const dds::core::policy::Presentation& presentation() const;

    const dds::core::policy::Partition& partition() const;

    const dds::core::policy::TopicData& topic_data() const;

    const dds::core::policy::GroupData& group_data() const;

#ifdef OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT
    const dds::core::policy::DataRepresentation& representation() const;

    const dds::core::policy::TypeConsistencyEnforcement&
    type_consistency() const;
#endif  // defined(OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT)

    // --- State: --- //
private:
    friend class OMG_DDS_PUBLICATION_BUILTIN_TOPIC_DATA_DELEGATE;
    DELEGATE impl_;
};

OMG_DDS_BUILTIN_TOPIC_TRAITS(PublicationBuiltinTopicData, "DDS_PublicationBuiltinTopicData", "DCPSPublication")


template <typename DELEGATE>
class tdds::domain::discovery::SubscriptionBuiltinTopicData :
    public dds::core::Value
{
    OMG_DDS_VALUE_TYPE(SubscriptionBuiltinTopicData)

public:
    const dds::domain::discovery::BuiltinTopicKey& key() const;

    const dds::domain::discovery::BuiltinTopicKey& participant_key() const;

    const std::string& topic_name() const;

    const std::string& type_name() const;

#ifdef OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT
    const dds::core::StringSeq& equivalent_type_name();

    const dds::core::StringSeq& base_type_name() const;

    const dds::type::typeobject::TypeObject& type() const;
#endif  // defined(OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT)

    const dds::core::policy::Durability& durability() const;

    const dds::core::policy::Deadline& deadline() const;

    const dds::core::policy::LatencyBudget& latency_budget() const;

    const dds::core::policy::Liveliness& liveliness() const;

    const dds::core::policy::Reliability& reliability() const;

    const dds::core::policy::UserData& user_data() const;

    const dds::core::policy::Ownership& ownership() const;

    const dds::core::policy::DestinationOrder& destination_order() const;

    const dds::core::policy::TimeBasedFilter& time_based_filter() const;

    const dds::core::policy::Presentation& presentation() const;

    const dds::core::policy::Partition& partition() const;

    const dds::core::policy::TopicData& topic_data() const;

    const dds::core::policy::GroupData& group_data() const;

#ifdef OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT
    const dds::core::policy::DataRepresentation& representation() const;

    const dds::core::policy::TypeConsistencyEnforcement&
    type_consistency() const;
#endif  // defined(OMG_DDS_EXTENSIBLE_AND_DYNAMIC_TOPIC_TYPE_SUPPORT)

    // --- State: --- //
private:
    friend class OMG_DDS_SUBSCRIPTION_BUILTIN_TOPIC_DATA_DELEGATE;
    DELEGATE impl_;
};

OMG_DDS_BUILTIN_TOPIC_TRAITS(SubscriptionBuiltinTopicData, "DDS_SubscriptionBuiltinTopicData", "DCPSSubscription")


#endif // !defined(OMG_DDS_BUILTINTOPICS_HPP_)
